Skip to content

Mol2 parse bonds - #170

Open
sukhmansaran wants to merge 2 commits into
BioPandas:mainfrom
sukhmansaran:mol2-parse-bonds
Open

sukhmansaran wants to merge 2 commits into
BioPandas:mainfrom
sukhmansaran:mol2-parse-bonds

Conversation

@sukhmansaran

Copy link
Copy Markdown

Code of Conduct

OK

Description

PandasMol2 only parsed the ATOM section, so getting the bonds of a molecule meant parsing pmol.mol2_text by hand. This PR adds BOND section parsing, following the API sketched in #54:

pmol = PandasMol2().read_mol2("1b5e_1.mol2")
pmol.parse_bonds()   # returns the DataFrame
pmol.df_bonds        # same DataFrame, stored on the object
   bond_id  origin_atom_id  target_atom_id bond_type status_bits
0        1               1               2         2
1        2               1               3         1
2        3               2              11         1

Design choices:

  • Bonds are parsed on request only. As suggested in Mol2 files bonds #54, read_mol2 is unchanged and doesn't parse bonds, so nothing gets slower for existing users. df_bonds is None until parse_bonds() is called. It is reset to None when a new molecule is read into the same object, so it can't hold bonds from the previous molecule. Like df, it can't be assigned to directly: it raises an AttributeError that points to _df_bonds.
  • Columns follow the Tripos spec: bond_id, origin_atom_id and target_atom_id (int64), plus bond_type and status_bits (str). bond_type stays a string because Tripos bond types include am, ar, du, un and nc; the test files contain both am and ar bonds. status_bits is optional in the format and is the empty string when a bond doesn't specify it.
  • The section ends at the next @<TRIPOS> record or at the end of the file. Blank and # comment lines are skipped. A molecule without a BOND section (e.g. a single ion) gives an empty DataFrame with the same columns and dtypes. A record with fewer than 4 fields or a non-integer id raises a ValueError that quotes the line.
  • Parsing works from mol2_text, so it behaves the same for read_mol2, read_mol2_from_list and gzipped files.

Tests (tests/mol2/test_pandas_mol2.py):

  • test_parse_bonds checks the columns, dtypes, values and bond types for 1b5e_1.mol2, and that every bond refers to an atom in df.
  • test_parse_bonds_matches_header_counts checks, for all 83 molecules in the test data (40_mol2_files.mol2, its .gz, 1b5e_2.mol2, and the CRLF file empty_line.mol2), that the number of parsed bonds equals the bond count in the MOLECULE header.
  • Further tests cover status bits, comment and blank lines, a BOND section at the end of the file, a molecule with no bonds, the reset on a new read, the error messages, and the read-only df_bonds.

All 7 new tests fail on main (AttributeError: 'PandasMol2' object has no attribute 'parse_bonds') and pass with this change. I also added a "Parsing the BOND Section" section to the Mol2 tutorial (notebook and the generated .md), with outputs produced by running the code.

Related issues or pull requests

Fixes #54

Pull Request Checklist

  • Added a note about the modification or contribution to the ./docs/sources/CHANGELOG.md file (if applicable) (added to docs/CHANGELOG.md, where the current "Unreleased" section is)
  • Added appropriate unit test functions in the ./biopandas/*/tests directories (if applicable) (in tests/mol2/)
  • Modify documentation in the corresponding Jupyter Notebook under biopandas/docs/sources/ (if applicable) (docs/tutorials/Working_with_MOL2_Structures_in_DataFrames.ipynb and .md)
  • Ran PYTHONPATH='.' pytest ./biopandas -sv and make sure that all unit tests pass (full tests/ suite: 134 passed, 7 skipped, 13 xfailed with pandas 3.1.1; tests/mol2 also passes with pandas 2.3.3. tests/pdb/test_read_pdb.py was deselected locally because it needs network access to RCSB.)
  • Checked for style issues by running flake8 ./biopandas (no warnings on the changed files)

🤖 Generated with Claude Code

sukhmansaran and others added 2 commits November 4, 2026 23:55
Parses the BOND section into a DataFrame (bond_id, origin_atom_id, target_atom_id, bond_type, status_bits), also stored in PandasMol2.df_bonds. Bonds are parsed on request only, so read_mol2 is unchanged. Fixes BioPandas#54.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mol2 files bonds

1 participant